23742
17342
Por que certas strings aleatórias produzem cores quando inseridas como cores de fundo em HTML? Por exemplo:
 teste 
... produz um documento com um fundo vermelho em todos os navegadores e plataformas.
Curiosamente, enquanto chucknorri produz um fundo vermelho também, chucknorr produz um fundo amarelo.
O que está acontecendo aqui? 
É um resquício dos dias da Netscape:
Dígitos ausentes são tratados como 0 [...]. Um dígito incorreto é simplesmente interpretado como 0. Por exemplo, os valores # F0F0F0, F0F0F0, F0F0F, #FxFxFx e FxFxFx são todos iguais.
É da postagem do blog Um pequeno discurso retórico sobre a análise de cores do Microsoft Internet Explorer, que o cobre em grandes detalhes, incluindo tamanhos variados de valores de cores, etc.
Se aplicarmos as regras da postagem do blog, obteremos o seguinte:
Substitua todos os caracteres hexadecimais não válidos por 0s:
chucknorris torna-se c00c0000000
Expanda até o próximo número total de caracteres divisíveis por 3 (11 → 12):
c00c 0000 0000
Dividido em três grupos iguais, com cada componente representando o componente de cor correspondente de uma cor RGB:
RGB (c00c, 0000, 0000)
Trunque cada um dos argumentos da direita para baixo em dois caracteres.
O que, finalmente, dá o seguinte resultado:
RGB (c0, 00, 00) = # C00000 ou RGB (192, 0, 0)
Aqui está um exemplo que demonstra o atributo bgcolor em ação, para produzir esta amostra de cor "incrível":
mandril norris Sr. T ninjaturtle
doente merda grama
Isso também responde à outra parte da pergunta: Por que bgcolor = "chucknorr" produz uma cor amarela? Bem, se aplicarmos as regras, a string será: c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)] O que dá uma cor de ouro amarelo claro. Como a string começa com 9 caracteres, mantemos o segundo 'C' desta vez, portanto, termina no valor de cor final. Eu originalmente encontrei isso quando alguém disse que você poderia fazer color = "crap" e, bem, sai marrom. | Lamento discordar, mas de acordo com as regras para analisar um valor de cor legado postado por @Yuhong Bao, chucknorris NÃO equivale a # CC0000, mas sim a # C00000, um tom de vermelho muito semelhante, mas ligeiramente diferente. Usei o complemento Firefox ColorZilla para verificar isso. As regras declaram: faça a string com um comprimento múltiplo de 3 adicionando 0s: chucknorris0 separe a corda em 3 cordas de igual comprimento: chuc knor ris0 truncar cada string em 2 caracteres: ch kn ri mantenha os valores hexadecimais e adicione 0s quando necessário: C0 00 00 Consegui usar essas regras para interpretar corretamente as seguintes strings: Amuletos da sorte Sorte LuckBeALady LuckBeALadyTonight GangnamStyle ATUALIZAÇÃO: os respondentes originais que disseram que a cor era # CC0000, desde então, editaram suas respostas para incluir a correção. | A maioria dos navegadores simplesmente ignora quaisquer valores NÃO hexadecimais em sua string de cores, substituindo os dígitos não hexadecimais por zeros. ChuCknorris se traduz em c00c0000000. Neste ponto, o navegador dividirá a string em três seções iguais, indicando os valores de Vermelho, Verde e Azul: c00c 0000 0000. Bits extras em cada seção serão ignorados, o que torna o resultado final # c00000 que é uma cor avermelhada. Observe que isso não se aplica à análise de cores CSS, que segue o padrão CSS.

Avermelhado

O mesmo que acima

Preto

| O motivo é que o navegador não consegue entendê-lo e tenta de alguma forma traduzi-lo para o que ele pode entender e, neste caso, em um valor hexadecimal! ... chucknorris começa com c, que é o caractere reconhecido em hexadecimal, e também converte todos os caracteres não reconhecidos em 0! Portanto, chucknorris no formato hexadecimal torna-se: c00c00000000, todos os outros caracteres tornam-se 0 ec permanece onde estão ... Agora eles são divididos por 3 para RGB (vermelho, verde, azul) ... R: c00c, G: 0000, B: 0000 ... Mas sabemos que hexadecimal válido para RGB tem apenas 2 caracteres, significa R: c0, G: 00, B: 00 Portanto, o resultado real é: bgcolor = "# c00000"; Também adicionei as etapas na imagem como uma referência rápida para você: | O navegador está tentando converter chucknorris em código de cor hexadecimal, porque não é um valor válido. No chucknorris, tudo, exceto c, não é um valor hexadecimal válido. Portanto, ele é convertido para c00c00000000. Que se torna # c00000, um tom de vermelho. Este parece ser um problema principalmente com o Internet Explorer e Opera (12), já que o Chrome (31) e o Firefox (26) simplesmente ignoram isso. P.S. Os números entre colchetes são as versões do navegador em que testei. Em uma nota mais leve Chuck Norris não está em conformidade com os padrões da web. Os padrões da web estão em conformidade para ele. # BADA55 | A especificação WHATWG HTML tem o algoritmo exato para analisar uma cor legadavalor: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. O código Netscape Classic usado para analisar strings de cores é de código aberto: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Por exemplo, observe que cada caractere é analisado como um dígito hexadecimal e, em seguida, é deslocado para um inteiro de 32 bits sem verificar o estouro. Apenas oito dígitos hexadecimais cabem em um inteiro de 32 bits, razão pela qual apenas os últimos 8 caracteres são considerados. Depois de analisar os dígitos hexadecimais em inteiros de 32 bits, eles são truncados em inteiros de 8 bits dividindo-os por 16 até que se ajustem aos 8 bits, motivo pelo qual os zeros à esquerda são ignorados. Atualização: Este código não corresponde exatamente ao que está definido na especificação, mas a única diferença são algumas linhas de código. Acho que foram essas linhas que foram adicionadas (no Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; } | Responda: O navegador tentará converter chucknorris em um valor hexadecimal. Como c é o único caractere hexadecimal válido em chucknorris, o valor se transforma em: c00c00000000 (0 para todos os valores inválidos). O navegador então divide o resultado em 3 grupos: Vermelho = c00c, Verde = 0000, Azul = 0000. Como os valores hexadecimais válidos para planos de fundo html contêm apenas 2 dígitos para cada tipo de cor (r, g, b), os últimos 2 dígitos são truncados de cada grupo, deixando um valor rgb de c00000 que é uma cor com tons avermelhados. | chucknorris começa com c, e o navegador lê em um valor hexadecimal. Porque A, B, C, D, E e F são caracteres em hexadecimal. O navegador converte chucknorris em um valor hexadecimal, C00C00000000. Em seguida, o valor hexadecimal C00C00000000 é convertido para o formato RGB (dividido por 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 O navegador precisa de apenas dois dígitos para indicar a cor: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Finalmente, mostre bgcolor = C00000 no navegador da web. Aqui está um exemplo que demonstra isso:
chucknorris c00c00000000 c00000
| As regras para analisar cores em atributos legados envolvem etapas adicionais às mencionadas nas respostas existentes. O componente truncar para a parte de 2 dígitos é descrito como: Descartar todos os caracteres, exceto os últimos 8 Descarte os zeros à esquerda um por um, desde que todos os componentes tenham um zero à esquerda Descarte todos os personagens, exceto os 2 primeiros Alguns exemplos: oooFoooFoooF 000F 000F 000F <- substituir, preencher e chunk 0F 0F 0F <- zeros à esquerda truncados 0F 0F 0F <- truncado para 2 caracteres da direita oooFooFFoFFF 000F 00FF 0FFF <- substituir, preencher e chunk 00F 0FF FFF <- zeros à esquerda truncados 00 0F FF <- truncado para 2 caracteres da direita ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- substituir, preencher e separar BC000000 BC000000 BC000000 <- truncado em 8 caracteres da esquerda BC BC BC <- truncado para 2 caracteres da direita AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- substituir, preencher e chunk 0C000000 0C000000 0C000000 <- truncado em 8 caracteres da esquerda C000000 C000000 C000000 <- zeros à esquerda truncados C0 C0 C0 <- truncado para 2 caracteres da direita Abaixo está uma implementação parcial do algoritmo. Ele não lida com erros ou casos em que o usuário insere uma cor válida. function parseColor (input) { // todo: retorna erro se a entrada for "" input = input.trim (); // todo: retorna erro se a entrada for "transparente" // todo: retorna o #rrggbb correspondente se a entrada for uma cor nomeada // todo: retorna #rrggbb se a entrada corresponder a #rgb // todo: substitui pontos de código Unicode maiores que U + FFFF por 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { input + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); b = b.slice (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# entrada"). on ("alterar", função () { var input = $ (this) .val (); var color = parseColor (entrada); var $ células = $ ("# resultado tbody td"); $ cells.eq (0) .attr ("bgcolor", entrada); $ cells.eq (1) .attr ("bgcolor", cor); varvalor: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. O código Netscape Classic usado para analisar strings de cores é de código aberto: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Por exemplo, observe que cada caractere é analisado como um dígito hexadecimal e, em seguida, é deslocado para um inteiro de 32 bits sem verificar o estouro. Apenas oito dígitos hexadecimais cabem em um inteiro de 32 bits, razão pela qual apenas os últimos 8 caracteres são considerados. Depois de analisar os dígitos hexadecimais em inteiros de 32 bits, eles são truncados em inteiros de 8 bits dividindo-os por 16 até que se ajustem aos 8 bits, motivo pelo qual os zeros à esquerda são ignorados. Atualização: Este código não corresponde exatamente ao que está definido na especificação, mas a única diferença são algumas linhas de código. Acho que foram essas linhas que foram adicionadas (no Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; } | Responda: O navegador tentará converter chucknorris em um valor hexadecimal. Como c é o único caractere hexadecimal válido em chucknorris, o valor se transforma em: c00c00000000 (0 para todos os valores inválidos). O navegador então divide o resultado em 3 grupos: Vermelho = c00c, Verde = 0000, Azul = 0000. Como os valores hexadecimais válidos para planos de fundo html contêm apenas 2 dígitos para cada tipo de cor (r, g, b), os últimos 2 dígitos são truncados de cada grupo, deixando um valor rgb de c00000 que é uma cor com tons avermelhados. | chucknorris começa com c, e o navegador lê em um valor hexadecimal. Porque A, B, C, D, E e F são caracteres em hexadecimal. O navegador converte chucknorris em um valor hexadecimal, C00C00000000. Em seguida, o valor hexadecimal C00C00000000 é convertido para o formato RGB (dividido por 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 O navegador precisa de apenas dois dígitos para indicar a cor: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Finalmente, mostre bgcolor = C00000 no navegador da web. Aqui está um exemplo que demonstra isso:
chucknorris c00c00000000 c00000
| As regras para analisar cores em atributos legados envolvem etapas adicionais às mencionadas nas respostas existentes. O componente truncar para a parte de 2 dígitos é descrito como: Descartar todos os caracteres, exceto os últimos 8 Descarte os zeros à esquerda um por um, desde que todos os componentes tenham um zero à esquerda Descarte todos os personagens, exceto os 2 primeiros Alguns exemplos: oooFoooFoooF 000F 000F 000F <- substituir, preencher e chunk 0F 0F 0F <- zeros à esquerda truncados 0F 0F 0F <- truncado para 2 caracteres da direita oooFooFFoFFF 000F 00FF 0FFF <- substituir, preencher e chunk 00F 0FF FFF <- zeros à esquerda truncados 00 0F FF <- truncado para 2 caracteres da direita ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- substituir, preencher e separar BC000000 BC000000 BC000000 <- truncado em 8 caracteres da esquerda BC BC BC <- truncado para 2 caracteres da direita AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- substituir, preencher e chunk 0C000000 0C000000 0C000000 <- truncado em 8 caracteres da esquerda C000000 C000000 C000000 <- zeros à esquerda truncados C0 C0 C0 <- truncado para 2 caracteres da direita Abaixo está uma implementação parcial do algoritmo. Ele não lida com erros ou casos em que o usuário insere uma cor válida. function parseColor (input) { // todo: retorna erro se a entrada for "" input = input.trim (); // todo: retorna erro se a entrada for "transparente" // todo: retorna o #rrggbb correspondente se a entrada for uma cor nomeada // todo: retorna #rrggbb se a entrada corresponder a #rgb // todo: substitui pontos de código Unicode maiores que U + FFFF por 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { input + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); b = b.slice (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# entrada"). on ("alterar", função () { var input = $ (this) .val (); var color = parseColor (entrada); var $ células = $ ("# resultado tbody td"); $ cells.eq (0) .attr ("bgcolor", entrada); $ cells.eq (1) .attr ("bgcolor", cor); var